#ifndef __DOUBLELINKLIST_H_
#define __DOUBLELINKLIST_H_

#include <stddef.h>
#include <iostream>

class DoubleLinkList
{
public:
    using ElementType = void *;

    void SetPrint(void (*Print)(void *))
    {
        this->Print = Print;
    }
    void SetCompare(int (*Compare)(void *, void *))
    {
        this->Compare = Compare;
    }

    size_t Size()
    {
        return size;
    }

    DoubleLinkList();
    // 拷贝构造   赋值运算符重载
    DoubleLinkList(const DoubleLinkList &list);
    DoubleLinkList &operator=(const DoubleLinkList &list);
    ~DoubleLinkList();
    void InsertTail(const ElementType &element);
    void InsertByIndex(size_t index, const ElementType &element);
    // 删除 2个
    void RemoveByIndex(size_t index);
    // 按值删除
    void RemoveByElemnt(const ElementType &element);

    // 查找2个
    // 按位置查找
    ElementType *FindByIndex(size_t index);
    // 按值查找
    DoubleLinkList FindByElement(const ElementType& element);

    // 修改2个
    // 按位置修改
    void UpdateByIndex(size_t index, const ElementType &element);
    // 按值修改
    void UpdateByElement(const ElementType &oldvalue, const ElementType &newvalue);
    // 排序 快速排序
    void Sort();
    // 归并
    DoubleLinkList Merge(const DoubleLinkList &list);
    void show();

private:
    struct Node
    {
        Node(const ElementType &value)
        {
            this->value = value;
            next = nullptr;
            prev = nullptr;
        }
        ElementType value; // 数据域
        Node *next;        // 前驱指针
        Node *prev;        // 后驱指针
    };
    void FastSort(Node *start, Node *end);
    Node *head; // 头指针
    Node *tail; // 尾指针
    size_t size;
    void (*Print)(void *);
    int (*Compare)(ElementType element1, ElementType element2);
};

#endif
